# 107. 对局匹配(好题)
# https://www.lanqiao.cn/problems/107/learning/?page=1&first_category_id=1&second_category_id=3&contain_answer=true
# Date: 2025/2/5
from collections import Counter, defaultdict


def game_match(players, k):
    cnt = Counter(players)  # 统计每个分数出现的次数

    # 特殊情况：k == 0
    # 同一分数的两个用户冲突，因为差为 0，所以每个分数最多只能选1个
    if k == 0:
        return len(cnt)

    # 将不同分数按“模 k”分组
    groups = defaultdict(list)
    for score in cnt:
        # score 与 score+k 必然落在同一个模 k 的组中
        groups[score % k].append(score)

    total = 0
    # 分别处理每个余数组
    for r, arr in groups.items():
        # 排序当前组中的分数
        arr.sort()

        m = len(arr)
        # 定义 dp[i] 表示前 i 个数（arr[0] 到 arr[i-1]）的最大贡献值
        dp = [0] * (m + 1)

        # 初始状态
        dp[0] = 0
        dp[1] = cnt[arr[0]]  # 贡献值为该分数的出现次数

        # 从前向后进行 DP
        for i in range(2, m + 1):
            contribution = cnt[arr[i - 1]]
            # 判断当前数 arr[i-1] 与上一个数 arr[i-2] 是否冲突
            if arr[i - 1] - arr[i - 2] == k:
                # 若冲突，则选 arr[i-1]时必须跳过上一个数的贡献
                dp[i] = max(dp[i - 1], dp[i - 2] + contribution)
            else:
                # 若不冲突，则可以直接累加
                dp[i] = dp[i - 1] + contribution
        total += dp[m]
    return total


if __name__ == '__main__':
    # n, k = map(int, input().split())
    # players = list(map(int, input().split()))
    players = [1, 4, 2, 8, 5, 7, 1, 4, 2, 8]
    print(game_match(players, 0))  # 6 [1,2,4,5,7,8]

    print(game_match(players, 2))  # 7 [1,1,2,2,7,8,8]

    with open('../data/107.in') as file:
        n, k = map(int, file.readline().split())
        players = list(map(int, file.readline().split()))

    print(game_match(players, k))  # 50611
